package com.wingsfrog.RCPSound;

import android.graphics.Bitmap;
import android.util.Base64;
import com.youzhuan.remote.music.device.*;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;

import com.youzhuan.remote.music.device.RemoteDeviceManager.OnDeviceStateListener;
import com.youzhuan.remote.music.device.RemoteDeviceManager.OnDeviceReturnListener;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.util.Map;
import java.util.Vector;

public class RCPSound extends CordovaPlugin implements OnDeviceStateListener, OnDeviceReturnListener {
    private CallbackContext callbackContext;
    private CallbackContext timerTaskContext;
    private CallbackContext systemTimeContext;
    private CallbackContext sleepSettingContext;
    private RemoteDeviceManager rdm;
    private boolean listen;

    @Override
    protected void pluginInitialize() {
        super.pluginInitialize();

        // 初始化
        this.rdm = RemoteDeviceManager.getInstance(this.cordova.getActivity().getApplicationContext());
        this.rdm.Create();
        this.listen = false;
    }

    @Override
    public boolean execute(String action, final JSONArray args, final CallbackContext context) throws JSONException {
        if ("init".equals(action)) {
            this.callbackContext = context; // 事件回调
        } else if ("reset".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    reset();
                    context.success();
                }
            });
        } else if ("stopListen".equals(action)) {
            if (!listen) context.error("没有监听");
            else {
                rdm.setOnDeviceStateListener(this, false);
                rdm.setOnDeviceReturnListener(this, false);
                context.success();
                listen = false;
            }
        } else if ("startListen".equals(action)) {
            if (listen) context.error("已经监听");
            else {
                this.rdm.setOnDeviceStateListener(this, true);
                this.rdm.setOnDeviceReturnListener(this, true);
                context.success();
                listen = true;
            }
        } else if ("getAllDevice".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    getAllDevices(context);
                }
            });
        } else if ("allPlay".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    rdm.doAllPlay();
                }
            });
        } else if ("allPlayLocal".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    rdm.doAllPlayLOCAL();
                }
            });
        } else if ("allPlayAux".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    rdm.doAllPlayAUX();
                }
            });
        } else if ("allPause".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    rdm.doAllPause();
                }
            });
        } else if ("allPowerOff".equals(action)) {
            cordova.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    rdm.doAllPowerOff();
                }
            });
        } else {
            final String mac = args.getString(0);
            if ("switchSoundSource".equals(action)) {
                final int source = args.getInt(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        switchSoundSource(mac, source, context);
                    }
                });
            } else if ("setPlayMode".equals(action)) {
                final int mode = args.getInt(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        setPlayMode(mac, mode, context);
                    }
                });
            } else if ("setEqMode".equals(action)) {
                final int mode = args.getInt(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        setEqMode(mac, mode, context);
                    }
                });
            } else if ("setVolume".equals(action)) {
                final int volume = args.getInt(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        setVolume(mac, volume, context);
                    }
                });
            } else if ("volumeIncrease".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        volumeIncrease(mac, context);
                    }
                });
            } else if ("volumeDecrease".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        volumeDecrease(mac, context);
                    }
                });
            } else if ("playPrev".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        playPrev(mac, context);
                    }
                });
            } else if ("playNext".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        playNext(mac, context);
                    }
                });
            } else if ("playResume".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        playResume(mac, context);
                    }
                });
            } else if ("playPause".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        playPause(mac, context);
                    }
                });
            } else if ("playMusicById".equals(action)) {
                final int musicId = args.getInt(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        playMusicById(mac, musicId, context);
                    }
                });
            } else if ("setPlayProgress".equals(action)) {
                final int progress = args.getInt(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        setPlayProgress(mac, progress, context);
                    }
                });
            } else if ("startMusicApp".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        startMusicApp(mac, context);
                    }
                });
            } else if ("getMusicCover".equals(action)) {
                final String path = args.getString(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        getMusicCover(mac, path, context);
                    }
                });
            } else if ("powerOff".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        powerOff(mac, context);
                    }
                });
            } else if ("rename".equals(action)) {
                final String name = args.getString(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        rename(mac, name, context);
                    }
                });
            } else if ("modifyTime".equals(action)) {
                final long tick = args.getLong(1);
                final String zone = args.getString(2);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        modifyTime(mac, tick, zone, context);
                    }
                });
            } else if ("modifySleepSetting".equals(action)) {
                final int index = args.getInt(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        modifySleepSetting(mac, index, context);
                    }
                });
            } else if ("modifyTimerTask".equals(action)) {
                final JSONArray tasks = args.getJSONArray(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        modifyTimerTask(mac, tasks, context);
                    }
                });
            } else if ("setAutoGetSystemTime".equals(action)) {
                final boolean auto = args.getBoolean(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        setAutoGetSystemTime(mac, auto, context);
                    }
                });
            } else if ("setAutoGetSleepSetting".equals(action)) {
                final boolean auto = args.getBoolean(1);
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        setAutoGetSleepSetting(mac, auto, context);
                    }
                });
            } else if ("isAutoGetSystemTime".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        isAutoGetSystemTime(mac, context);
                    }
                });
            } else if ("isAutoGetSleepSetting".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        isAutoGetSleepSetting(mac, context);
                    }
                });
            } else if ("getTimerTask".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        getTimerTask(mac, context);
                    }
                });
            } else if ("getSystemTime".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        getSystemTime(mac, context);
                    }
                });
            } else if ("getSleepSetting".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        getSleepSetting(mac, context);
                    }
                });
            } else if ("addCurToFavorite".equals(action)) {
                cordova.getThreadPool().execute(new Runnable() {
                    @Override
                    public void run() {
                        addCurToFavorite(mac, context);
                    }
                });
            } else
                return false;
            return true;
        }
        return true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        RemoteDeviceManager rdm = RemoteDeviceManager.getInstance(this.cordova.getActivity().getApplicationContext());
        // 取消监听
        rdm.setOnDeviceStateListener(this, false);
        rdm.setOnDeviceReturnListener(this, false);

        // 释放
        rdm.Destroy();
    }

    private JSONObject PlayStateToJson(final RDevice device) throws JSONException {
        JSONObject obj = new JSONObject();
        RPlayState playState = device.mPlayState;
        obj.put("cbType", "stateChange");
        obj.put("mac", device.mStatus.mMac);

        JSONObject ss = new JSONObject();
        PlayListToJson(device.mMapSS, ss);
        obj.put("soundSource", ss);

        obj.put("eqModel", playState.ex_EQMode);
        obj.put("flagLocal", playState.ex_FlagLocal);
        obj.put("mute", playState.ex_Mute);
        obj.put("playMode", playState.ex_PlayMode);
        obj.put("tickCountTmp", playState.ex_TickCountTmp);
        obj.put("volumeCur", playState.ex_VolumeCur);
        obj.put("volumeMax", playState.ex_VolumeMax);
        obj.put("volumeTmp", playState.ex_VolumeTmp);
        // obj.put("fileCover", playState.mFileCover);
        obj.put("playStatus", playState.mPlayStatus);
        obj.put("alumId", playState.music_alumid);
        obj.put("artist", playState.music_artist);
        obj.put("duration", playState.music_duration);
        obj.put("musicId", playState.music_musicid);
        obj.put("musicName", playState.music_name);
        obj.put("musicPath", playState.music_path);
        obj.put("musicTime", playState.music_time);
        return obj;
    }

    private JSONObject RDeviceToJson(final RDevice rd) throws JSONException {
        JSONObject obj = new JSONObject();
        RStatus mStatus = rd.mStatus;
        RPlayState playState = rd.mPlayState;
        obj.put("cbType", "device");

        JSONObject ss = new JSONObject();
        PlayListToJson(rd.mMapSS, ss);
        obj.put("soundSource", ss);

        obj.put("eqModel", playState.ex_EQMode);
        obj.put("flagLocal", playState.ex_FlagLocal);
        obj.put("mute", playState.ex_Mute);
        obj.put("playMode", playState.ex_PlayMode);
        obj.put("tickCountTmp", playState.ex_TickCountTmp);
        obj.put("volumeCur", playState.ex_VolumeCur);
        obj.put("volumeMax", playState.ex_VolumeMax);
        obj.put("volumeTmp", playState.ex_VolumeTmp);
        // obj.put("fileCover", playState.mFileCover);
        obj.put("playStatus", playState.mPlayStatus);
        obj.put("alumId", playState.music_alumid);
        obj.put("artist", playState.music_artist);
        obj.put("duration", playState.music_duration);
        obj.put("musicId", playState.music_musicid);
        obj.put("musicName", playState.music_name);
        obj.put("musicPath", playState.music_path);
        obj.put("musicTime", playState.music_time);

        obj.put("dlnaUDN", mStatus.mDlnaUDN);
        obj.put("hostIp", mStatus.mHostIP);
        obj.put("hostPort", mStatus.mHostPort);
        obj.put("isLinkCtrl", mStatus.mIsLinkCtrl);
        obj.put("isLinkDlna", mStatus.mIsLinkDlna);
        obj.put("mac", mStatus.mMac);
        obj.put("name", mStatus.mName);
        obj.put("netState", mStatus.mNetState);
        obj.put("player", mStatus.mPlayer);
        obj.put("type", mStatus.mType);
        return obj;
    }

    private void reset() {
        // 取消监听
        this.rdm.setOnDeviceStateListener(this, false);
        this.rdm.setOnDeviceReturnListener(this, false);
        // 释放
        this.rdm.Destroy();

        this.rdm = RemoteDeviceManager.getInstance(this.cordova.getActivity().getApplicationContext());
        this.rdm.Create();
        // 监听
        this.rdm.setOnDeviceStateListener(this, true);
        this.rdm.setOnDeviceReturnListener(this, true);
        this.listen = true;
    }

    private void switchSoundSource(final String mac, final int source, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doSwitchSoundSource(source);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void setPlayMode(final String mac, final int mode, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doSetPlayMode(mode);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void setEqMode(final String mac, final int mode, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doSetEQMode(mode);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void setVolume(final String mac, final int volume, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doSetVolume(volume);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void volumeIncrease(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.volumeIncrease();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void volumeDecrease(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.volumeDecrease();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void playPrev(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doPlayPrev();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void playNext(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doPlayNext();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void playResume(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doPlayResume();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void playPause(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doPlayPause();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void playMusicById(final String mac, final int id, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doPlayMusicById(id);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void setPlayProgress(final String mac, final int progress, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doSetPlayProgress(progress);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void startMusicApp(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doStartMusicApp();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void getMusicCover(final String mac, final String path, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doGetMusicCover(path);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void powerOff(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doPowerOff();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void rename(final String mac, final String name, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doRename(name);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void modifyTime(final String mac, final long tick, final String zone, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doModifySystemTime(tick, zone);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void modifySleepSetting(final String mac, final int index, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doModifySleepSetting(index);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void modifyTimerTask(final String mac, final JSONArray task, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            try {
                Vector<RAlarm> vector = new Vector<RAlarm>();
                int l = task.length();
                for (int i = 0; i < l; i++) {
                    JSONObject obj = task.getJSONObject(i);
                    RAlarm rAlarm = new RAlarm();
                    rAlarm.alert = obj.getString("alert");
                    rAlarm.audiosrc = obj.getInt("audiosrc");
                    rAlarm.daysOfWeek = obj.getInt("daysOfWeek");
                    rAlarm.enabled = obj.getBoolean("enabled");
                    rAlarm.hour = obj.getInt("hour");
                    rAlarm.id = obj.getInt("id");
                    rAlarm.isPowerOff = obj.getBoolean("isPowerOff");
                    rAlarm.isShow = obj.getBoolean("isShow");
                    rAlarm.label = obj.getString("label");
                    rAlarm.minutes = obj.getInt("minutes");
                    rAlarm.silent = obj.getBoolean("silent");
                    rAlarm.type = obj.getString("type");
                    rAlarm.vibrate = obj.getBoolean("vibrate");
                    rAlarm.volume = obj.getInt("volume");
                    vector.add(rAlarm);
                }
                device.doModifyTimerTask(vector);
                context.success();
            } catch (JSONException e) {
                context.error(e.getMessage());
            }
        } else {
            context.error("设备未上线");
        }
    }
    private void setAutoGetSystemTime(final String mac, final boolean auto, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.setAutoGetSystemTime(auto);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void setAutoGetSleepSetting(final String mac, final boolean auto, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.setAutoGetSleepSetting(auto);
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void isAutoGetSystemTime(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            boolean r = device.isAutoGetSystemTime();
            PluginResult result = new PluginResult(PluginResult.Status.OK, r);
            context.sendPluginResult(result);
        } else {
            context.error("设备未上线");
        }
    }
    private void isAutoGetSleepSetting(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            boolean r = device.isAutoGetSleepSetting();
            PluginResult result = new PluginResult(PluginResult.Status.OK, r);
            context.sendPluginResult(result);
        } else {
            context.error("设备未上线");
        }
    }
    private void getTimerTask(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doGetTimerTask();
            this.timerTaskContext = context;
        } else {
            context.error("设备未上线");
        }
    }
    private void getSystemTime(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doGetSystemTime();
            this.systemTimeContext = context;
        } else {
            context.error("设备未上线");
        }
    }
    private void getSleepSetting(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doGetSleepSetting();
            this.sleepSettingContext = context;
        } else {
            context.error("设备未上线");
        }
    }
    private void addCurToFavorite(final String mac, final CallbackContext context) {
        RDevice device = null;
        if (mac != null) {
            device = this.rdm.getDeviceByMac(mac);
        } else {
            context.error("Mac地址不合法");
        }
        if (device != null) {
            device.doAddCurToFavorite();
            context.success();
        } else {
            context.error("设备未上线");
        }
    }
    private void getAllDevices(CallbackContext context) {
        try {
            Vector<RDevice> rDevices = rdm.doGetDevices();
            JSONArray array = new JSONArray();
            for (RDevice device: rDevices) {
                array.put(RDeviceToJson(device));
            }
            context.success(array);
        } catch (JSONException e) {
            context.error(e.getMessage());
        }
    }

    // 发现新设备
    public void onDeviceNew(final RDevice rd) {
        PluginResult result;
        try {
            result = new PluginResult(PluginResult.Status.OK, RDeviceToJson(rd));
        } catch (JSONException e) {
            result = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
        }
        result.setKeepCallback(true);
        this.callbackContext.sendPluginResult(result);
    }

    // 设备名称改变
    public void onDeviceNameChange(final RDevice rd) {
        JSONObject obj = new JSONObject();
        PluginResult result;
        try {
            obj.put("cbType", "nameChange");
            obj.put("newName", rd.mStatus.mName);
            obj.put("mac", rd.mStatus.mMac);
            result = new PluginResult(PluginResult.Status.OK, obj);
        } catch (JSONException e) {
            result = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
        }
        result.setKeepCallback(true);
        this.callbackContext.sendPluginResult(result);
    }

    // 播放器运行状态改变
    public void onDeviceAppStatusChange(final RDevice rd) {
        System.out.println(rd.mPlayState.ex_VolumeCur);
//        this.callbackContext.success("播放运行状态" + rd.mPlayState.music_name);
    }

    private void PlayListToJson(final Map<String, RDevice.SoundSource> mMapSS, JSONObject obj)
            throws JSONException {
        for (String key: mMapSS.keySet()) {
            JSONArray array = new JSONArray();
            RDevice.SoundSource soundSource = mMapSS.get(key);
            for (Map<String, Object> mFile : soundSource.mFiles) {
                JSONObject innerObj = new JSONObject();
                for(String innerKey: mFile.keySet()) {
                    innerObj.put(innerKey, mFile.get(innerKey));
                }
                array.put(innerObj);
            }
            obj.put(key, array);
        }
    }
    // 音乐列表刷新
    public void onDeviceMusicListRefresh(final RDevice rd) {
        Map<String, RDevice.SoundSource> mMapSS = rd.mMapSS;
        JSONObject obj = new JSONObject();
        PluginResult result;
        try {
            obj.put("cbType", "soundSource");
            obj.put("mac", rd.mStatus.mMac);
            PlayListToJson(rd.mMapSS, obj);
            result = new PluginResult(PluginResult.Status.OK, obj);
        } catch (JSONException e) {
            result = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
        }
        result.setKeepCallback(true);
        this.callbackContext.sendPluginResult(result);
    }

    // 音乐封面
    public void onDeviceMusicCover(final RDevice rd) {
        if (rd.mPlayState.mFileCover == null) return;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        rd.mPlayState.mFileCover.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] imageBytes = baos.toByteArray();
        String encodeImage = "data:image/png;base64," + Base64.encodeToString(imageBytes, Base64.DEFAULT);
        JSONObject obj = new JSONObject();
        PluginResult result;
        try {
            obj.put("cbType", "cover");
            obj.put("mac", rd.mStatus.mMac);
            obj.put("cover", encodeImage);
            result = new PluginResult(PluginResult.Status.OK, obj);
        } catch (JSONException e) {
            result = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
        }
        result.setKeepCallback(true);
        this.callbackContext.sendPluginResult(result);
    }

    // 播放状态
    public void onDeviceMusicPlayState(final RDevice rd) {
        PluginResult result;
        try {
            result = new PluginResult(PluginResult.Status.OK, PlayStateToJson(rd));
        } catch (JSONException e) {
            result = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
        }
        result.setKeepCallback(true);
        this.callbackContext.sendPluginResult(result);
    }

    // 网络状态
    public void onDeviceNetErrorState(final RDevice rd) {
//        this.callbackContext.success("网络状态" + rd.mStatus.mNetState);
    }

    // 开始播放新歌曲
    public void onDevicePlayNewMusic(final RDevice rd) {
        JSONObject obj = new JSONObject();
        PluginResult result;
        try {
            obj.put("cbType", "playNew");
            obj.put("musicName", rd.mPlayState.music_name);
            obj.put("mac", rd.mStatus.mMac);
            result = new PluginResult(PluginResult.Status.OK, obj);
        } catch (JSONException e) {
            result = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
        }
        result.setKeepCallback(true);
        this.callbackContext.sendPluginResult(result);
    }

    @Override
    // 睡眠设置(定时关机)
    public void onFunSleepSetting(RDevice rDevice, int i, long l, long l1, long l2) {
        JSONObject obj = new JSONObject();
        this.sleepSettingContext.success(obj);
        this.sleepSettingContext = null;
    }

    @Override
    // 系统时间
    public void onFunSystemTime(RDevice rDevice, long l) {
        try {
            JSONObject obj = new JSONObject();
            obj.put("mac", rDevice.mStatus.mMac);
            obj.put("time", l);
            this.systemTimeContext.success(obj);
        } catch (JSONException e) {
            this.systemTimeContext.error(e.getMessage());
        } finally {
            this.systemTimeContext = null;
        }
    }

    @Override
    // 定时任务(定时开机&关机)
    public void onFunTimerTask(RDevice rDevice, Vector<RAlarm> vector) {
        try {
            JSONObject obj = new JSONObject();
            obj.put("mac", rDevice.mStatus.mMac);

            JSONArray array = new JSONArray();
            obj.put("rAlarmList", array);

            for(RAlarm rAlarm: vector) {
                JSONObject innerObj = new JSONObject();
                innerObj.put("alert", rAlarm.alert);
                innerObj.put("audiosrc", rAlarm.audiosrc);
                innerObj.put("daysOfWeek", rAlarm.daysOfWeek);
                innerObj.put("enabled", rAlarm.enabled);
                innerObj.put("hour ", rAlarm.hour);
                innerObj.put("id ", rAlarm.id);
                innerObj.put("isPowerOff ", rAlarm.isPowerOff );
                innerObj.put("isShow ", rAlarm.isShow );
                innerObj.put("label", rAlarm.label);
                innerObj.put("minutes", rAlarm.minutes);
                innerObj.put("silent ", rAlarm.silent );
                innerObj.put("type", rAlarm.type);
                innerObj.put("vibrate", rAlarm.vibrate);
                innerObj.put("volume", rAlarm.volume);
                array.put(innerObj);
            }
            this.timerTaskContext.success(obj);
        } catch (JSONException e) {
            this.timerTaskContext.error(e.getMessage());
        } finally {
            this.timerTaskContext = null;
        }
    }
}
